/*
    This source file is part of GeNa project.
    Copyright © GeNa project 2008
    For the latest info, see http://code.google.com/p/genaproject/ or  http://lumpyproject.forums-rpg.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Foobar is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef SINGLETON_H_INCLUDED
#define SINGLETON_H_INCLUDED

//Used it to make a singleton for a class, “void init()” and “void destroy()” must be defined, eg :
//class Foo
//{
//private :
//    init()
//    {
//        ... Initialisation code
//    }
//
//    destroy()
//    {
//        ... Destruction code
//    }
//
//    MAKE_SINGLETON(Foo) now a singleton
//
//    ... class declaration
//};
//
//#define FooInstance MAKE_SINGLETON_PSEUDO_INSTANCE(Foo)
//
//The singleton can be now used like this
// FooInstance.aMethod()
//wich is equivalent to
// Foo::getInstance().aMethod()

#define MAKE_SINGLETON(a)   \
private:                    \
a()                         \
{                           \
    init();                 \
}                           \
                            \
a(const a&);                \
a& operator=(const a&);     \
~a()                        \
{                           \
    destroy();              \
}                           \
                            \
public:                     \
static a& getInstance()     \
{                           \
    static a A;             \
    return A;               \
}

//Same as before, but let the class define the default constructor and the destructor itself
#define MAKE_SINGLETON_NO_CTOR_DTOR(a)      \
private:                                    \
                                            \
a(const a&);                                \
a& operator=(const a&);                     \
                                            \
public:                                     \
static a& getInstance()                            \
{                                           \
    static a A;                             \
    return A;                               \
}

#define MAKE_SINGLETON_PSEUDO_INSTANCE(a) a::getInstance()

#endif // SINGLETON_H_INCLUDED
